/******************************************************************************
**
** Copyright 2010-2012 Alexey Khomich
**
** File name:	rtos.h
**
** Description:	RTOS (Real Time Operating System) for Atmel Xmega MCUs.
**				Version 3.0
**				Application header file. Do not modify this file!
**
** Author:		Alexey.Khomich@gmail.com
**
*******************************************************************************
** History:		
**  
**	10/05/2011	- AK -	RTOS v2. TASK/ISR services reimplemented
**						kernel/task/isr typedefs are changed
**  10/15/2011	- AK - 	Adding basic event management
**	11/14/2011	- AK - 	Cosmetic changes (var names, defs)
** 	11/15/2011 	- AK - 	Adding messages, message queues and timers
**	11/19/2011 	- AK -	Removing obsolete services, about to final revision for 
**						RTOS V.2
**	11/25/2011  - AK -  Adding resourse export macros
**	09/05/2012  - AK -  RTOS_StackCheck() fix
**	09/20/2012	- AK -  RTOS_DECLARE_ISR() macro reimplemented
**						RTOS_STACKCHECK() services reimplemeted
**	09/25/2012	- AK - 	RTOS_TaskResumeISR() / RTOS_TaskSuspendISR added
**	09/28/2012  - AK -  Safe call for RTOS_StackCheck() when stack checking
**						is switched off (#undefine RTOS_USE_STACKCHECK) 
**	10/09/2012  - AK -  Added timer message RTOS feature (services & 
**						configuration)
**	10/09/2012  - AK -  Adde RTOS_DECLARE_FAST_ISR()
** 
******************************************************************************/
#ifndef __RTOS_H__
#define __RTOS_H__

/******************************************************************************
** RTOS CONFIGURATION SECTION
******************************************************************************/
#define RTOS_VERSION_MAJOR				3		/* RTOS Version 3.0.6 */
#define RTOS_VERSION_MINOR				0
#define RTOS_VERSION_BUILD				6

#define RTOS_USE_STACKCHECK				1		/* Enable/Disable run-time stack verification capabilities */

/******************************************************************************
**
** Compiler related defines 
**
******************************************************************************/
#if !defined( __GNUC__ )  /* Supporting GNU toolchain from AVR Studio 5.0 */
#error "Error: No compiler is supported other than GNU Toolchain"
#endif

#define FLASH			__attribute__ ((progmem))
#define EEPROM			__attribute__ ((section(".eeprom")))
#define NAKED			__attribute__ ((naked))
#define CTASK			__attribute__ ((OS_task)) 				/* formerly __attribute__((noreturn)) */
#define CMAIN			__attribute__ ((OS_main))				/* new in RTOS Version 3 */
#define NAKEDFUNC(A) 	void A( void )   NAKED;			\
						void A( void )
#define CTASKFUNC(A) 	void A( void ) 	 CTASK;			\
						void A( void )
#define CMAINFUNC()		int	main( void ) CMAIN;			\
						int main( void )
#define RTOS_API		 __attribute__ ((visibility ("default")))
#define OBSOLETE		 __attribute__ ((visibility ("hidden") ))


/******************************************************************************
** RTOS Type Definitions
******************************************************************************/
/* RTOS ELEMENTARY TYPES */
typedef unsigned char 	RTOS_U8_t;
typedef unsigned int  	RTOS_U16_t;
typedef unsigned long 	RTOS_U32_t;

/* RTOS KERNEL PRIVATE STRUCTURE */
typedef struct RTOS_KDATA_s
{
	struct RTOS_TCB_s *	queue;				// Head of the running tasks queue 
	struct RTOS_TCB_s *	running;			// Actually running task
	void *				stack;				// Kernel stack pointer
	RTOS_U8_t			level;				// System execution level 
	
}
RTOS_KDATA_t;

/* RTOS TASK CONTEXT */
/* RTOS CONTEXT TYPE */
typedef struct RTOS_CTX_s
{
	RTOS_U8_t				STACKTOP;		// Top of the task stack
	RTOS_U8_t				STATUSREG;		// MCU STATUS REGISTER
	RTOS_U8_t				R[32];			// REGISTERS R0 ... R31
	RTOS_U16_t				RETADDR;		// RETURN ADDRESS
//	U8			RET_HI;
//	U8			RET_LO;
}
RTOS_CTX_t, * RTOS_CTX_ptr;


/* RTOS TASK/ISR FUNCTIONS */
typedef void ( RTOS_TSK_t ) (void);
typedef void ( RTOS_ISR_t )	(void);

/* RTOS TCB - TASK CONFIGURATION BLOCK */
typedef struct RTOS_TCB_s					// RTOS Task Configuration Block (TCB)
{
    RTOS_U8_t *				stack;          // Start of stack (top address-1)
    RTOS_TSK_t *			task;   		// Entry point of code
    struct RTOS_PID_s *		pid;         	// Pointer to Task ID block
    RTOS_U8_t 				prio;       	// Priority of task (0-255)	
}
FLASH const RTOS_TCB_t;

/* RTOS PID - PROCESS (TASK) IDENTIFIER */
typedef struct RTOS_PID_s					
{
	struct RTOS_PID_s *		next;
	RTOS_U8_t	 			flag;
	RTOS_U8_t 				prio;
	RTOS_CTX_t *			sptr;
}
RTOS_PID_t, * RTOS_PID_ptr;

/* RTOS EVT - EVENT */
typedef struct RTOS_EVT_s
{
	struct RTOS_EVT_s *	next;
}
RTOS_EVT_t, * RTOS_EVT_ptr;

/* RTOS EST - EVENT STATE */
typedef enum RTOS_EST_e
{
	EVT_PEND	= 0,						// Event Pending 
	EVT_DONE	= 1,						// Event Done
	EVT_WAIT	= 2,						// Something is waiting for the event	
}
RTOS_EST_t, * RTOS_EST_ptr;

/* RTOS MSG - MESSAGE */
typedef struct RTOS_MSG_s
{
    struct RTOS_MSG_s *		next;
    struct RTOS_EVT_s		event;
}
RTOS_MSG_t, * RTOS_MSG_ptr;

/* RTOS MSQ - MESSAGE QUEUE */
typedef struct RTOS_MSQ_s
{
    struct RTOS_MSG_s *		top;			// List of messages
    struct RTOS_PID_s *		pid;			// List of processes 
}
RTOS_MSQ_t, * RTOS_MSQ_ptr;

/* RTOS TMR - TIMER */
typedef struct RTOS_TMR_s
{
    struct RTOS_TMR_s *		next;
    struct RTOS_EVT_s		event;
    RTOS_U16_t 				count;
}
RTOS_TMR_t, * RTOS_TMR_ptr;

/* RTOS TMS - TIMER MESSAGE */
typedef struct RTOS_TMS_s
{
	union
	{
		RTOS_MSG_t		msg;
		RTOS_TMR_t		tmr;
	};
	RTOS_MSQ_t	* msq;
}
RTOS_TMS_t, * RTOS_TMS_ptr;

/* RTOS OBJ - OBJECT */
typedef union RTOS_OBJ_u
{
	struct RTOS_PID_s		pid;
	struct RTOS_MSG_s		msg;
	struct RTOS_MSQ_s		msq;
	struct RTOS_TMR_s		tmr;
}
RTOS_OBJ_t, * RTOS_OBJ_ptr;

/******************************************************************************
** RTOS CONSTANT DEFINITIONS
******************************************************************************/
#if !defined(NULL)
#	define	NULL	0
#endif

#define NOTASK		((RTOS_TCB_t *)NULL)
#define NOMESSAGE	((RTOS_MSG_t *)NULL)
#define NOTIMER		((RTOS_TMR_t *)NULL)

/******************************************************************************
** TASK DECLARATION/DEFINITION MACRO
******************************************************************************/
#if defined(RTOS_USE_STACKCHECK)

#define RTOS_DECLARE_TASK( __task__ , __stack__ , __prio__ ) 		\
	RTOS_U8_t	__task__##STK[__stack__ + sizeof(RTOS_CTX_t) + 8];	\
	void		__task__##FNC ( void ) __attribute__ ((noreturn));	\
	RTOS_PID_t	__task__##PID;										\
	RTOS_TCB_t	__task__##TCB = 									\
	{																\
		&__task__##STK[sizeof(__task__##STK) - 5],					\
		&__task__##FNC,												\
		&__task__##PID,												\
		__prio__,													\
	};																\
	void __attribute__((optimize("Os"))) 							\
		RTOS_StackCheck##__task__( void ) {							\
			if ( ( *(long *)(&__task__##STK[0]) != 0xDEADBEAFUL) || \
			   ( *(long *)(&__task__##STK[sizeof(__task__##STK) - 4]  ) != 0xDEADBEAFUL ) )   \
			RTOS_HaltOS();		 									\
			return;													\
		}															\
	void __attribute__((optimize("Os"))) 							\
		RTOS_StackInit##__task__( void ) {							\
			*((unsigned long *)(&__task__##STK[ 0])) = 0xDEADBEAFUL;\
			*((unsigned long *)(&__task__##STK[sizeof(__task__##STK) - 4])) = 0xDEADBEAFUL;	\
			return;													\
		}
#else

#define RTOS_DECLARE_TASK( __task__ , __stack__ , __prio__ ) 		\
	RTOS_U8_t	__task__##STK[__stack__ + sizeof(RTOS_CTX_t)];		\
	void		__task__##FNC ( void ) __attribute__ ((noreturn));	\
	RTOS_PID_t	__task__##PID;										\
	RTOS_TCB_t	__task__##TCB = 									\
	{																\
		&__task__##STK[sizeof(__task__##STK) - 1],					\
		&__task__##FNC,												\
		&__task__##PID,												\
		__prio__,													\
	}

#endif /* if defined(RTOS_USE_STACKCHECK) */
	
#define RTOS_TASK_FUNC( __task__ )									\
	CTASKFUNC(__task__##FNC)
		
/******************************************************************************
** RTOS INTERRUPT SERVICE ROUTINE DECLARATION/DEFINITION MACRO 
******************************************************************************/
#define STRINGIFY(x)	#x

#define RTOS_DECLARE_ISR( __vector__ , __handler__ )				\
	extern void __handler__ ## FNC ( void );						\
	NAKEDFUNC( __vector__ ) {										\
		asm volatile ( 												\
			"CLI\n"													\
			"CALL 	RTOS_EnterISR\n"								\
			"SEI\n"													\
			STRINGIFY( CALL 	__handler__ ## FNC\n )				\
			"JMP 	RTOS_LeaveISR\n"								\
			: : 													\
		);															\
	}


#define RTOS_DECLARE_FAST_ISR( __vector__ , __handler__ )			\
	extern void __handler__ ## ASM ( void );						\
	void __attribute__((signal, naked, used, externally_visible)) 	\
		__vector__ (void) { 										\
			asm volatile (											\
				STRINGIFY( JMP __handler__ ## ASM \n) 				\
				: :													\
			); 														\
		}
   
#define RTOS_ISR_FUNC( __handler__ )								\
	void __handler__ ## FNC ( void ) 

/******************************************************************************
** RTOS RESOURCES (EVENT/MESSAGE/QUEUE/TIMER) DECLARATION/DEFINITION MACRO 
******************************************************************************/
#define RTOS_DECLARE_EVENT( __evt__ )								\
	RTOS_EVT_t		__evt__

#define RTOS_DECLARE_MESSAGE( __msg__ )								\
    RTOS_MSG_t 		__msg__
	
#define RTOS_DECLARE_MESSAGE_EXP( __msg__ )							\
    RTOS_MSG_t 		__msg__;										\
	void *			__msg__##_dptr

#define RTOS_DECLARE_MESSAGEQ( __msq__ )							\
    RTOS_MSQ_t		__msq__

#define RTOS_DECLARE_TIMER( __tmr__ )								\
	RTOS_TMR_t		__tmr__
	
#define RTOS_DECLARE_TIMER_MESSAGE( __tms__ )						\
	RTOS_TMS_t		__tms__
	
/******************************************************************************
** RTOS RESOURCE (TASK/ISR/EVENT/MESSAGE/QUEUE/TIMER) EXPORT MACROS
******************************************************************************/	
#if defined(RTOS_USE_STACKCHECK)

#define EXPORT_RTOS_TASK( __tsk__ )									\
	extern void RTOS_StackCheck##__tsk__( void );					\
	extern void RTOS_StackInit##__tsk__( void );					\
	extern void __tsk__##FNC( void ) __attribute__((noreturn));		\
	extern RTOS_U8_t *	__tsk__##STK;								\
	extern RTOS_TCB_t 	__tsk__##TCB;	 							\
	extern RTOS_PID_t 	__tsk__##PID

#else

#define EXPORT_RTOS_TASK( __tsk__ )									\
	extern void __tsk__##FNC( void) __attribute__((noreturn));		\
	extern RTOS_TCB_t 	__tsk__##TCB;	 							\
	extern RTOS_PID_t 	__tsk__##PID
	
#endif


#define EXPORT_RTOS_ISR( __isr__ )									\
	extern void __isr__##FNC( void )
	
#define EXPORT_RTOS_EVENT( __evt__ )								\
	extern RTOS_EVT_t	__evt__

#define EXPORT_RTOS_MESSAGE( __msg__ ) 								\
	extern RTOS_MSG_t	__msg__

#define EXPORT_RTOS_MESSAGE_EXP(__msg__)							\
	extern RTOS_MSG_t	__msg__;									\
	extern void *		__msg__##_dptr
	
#define EXPORT_RTOS_MESSAGEQ( __msq__ ) 							\
	extern RTOS_MSQ_t	__msq__

#define EXPORT_RTOS_TIMER( __tmr__ ) 								\
	extern RTOS_TMR_t	__tmr__

#define EXPORT_RTOS_TIMER_MESSAGE( __tms__ ) 						\
	extern RTOS_TMS_t	__tms__
	
/******************************************************************************
** RTOS API SERVICES
******************************************************************************/

/* RTOS KERNEL MANAGEMENT API */

#			define		RTOS_DisableInterrupt() asm volatile ("cli\n")
#			define		RTOS_EnableInterrupt()  asm volatile ("sei\n")
#			define 		RTOS_HaltOS()			asm volatile ("break\n")

RTOS_API 	void * 		RTOS_Initialize			( void * sptr );
RTOS_API 	void 		RTOS_StartOS			( void );
RTOS_API 	void 		RTOS_EnterISR	   		( void );
RTOS_API 	void 		RTOS_LeaveISR			( void );
//OBSOLETE 	void 		RTOS_HaltOS				( void );		// Halt Processor (debug only)

/* RTOS TASK MANAGEMENT API */

#if defined(RTOS_USE_STACKCHECK)

#	define 	RTOS_TaskStartExp( __task__ )							\
				RTOS_StackInit##__task__();							\
				RTOS_TaskStart(&(__task__##TCB))
		
#	define 	RTOS_TaskInitExp( __task__ )							\
		RTOS_StackInit##__task__();									\
				RTOS_TaskInit(&(__task__##TCB))
		
#	define	RTOS_StackCheck( __task__ )								\
				RTOS_StackCheck##__task__()

#else

#	define 	RTOS_TaskStartExp( __task__ )							\
				RTOS_TaskStart(&(__task__##TCB))

#	define 	RTOS_TaskInitExp( __task__ )							\
				RTOS_TaskInit(&(__task__##TCB))
		
#	define	RTOS_StackCheck( __task__ )

		
#endif	/* if defined(RTOS_USE_STACKCHECK) */

RTOS_API 	void 		RTOS_TaskStart			( RTOS_TCB_t * );
RTOS_API unsigned char 	RTOS_TaskInit			( RTOS_TCB_t * );
RTOS_API 	void 		RTOS_TaskResume			( RTOS_PID_t * );
RTOS_API 	void 		RTOS_TaskSuspend		( RTOS_PID_t * );
RTOS_API 	void 		RTOS_TaskTerminate		( RTOS_PID_t * );
RTOS_API 	void 		RTOS_TaskExit			( void );
// obsolete RTOS_API RTOS_U8_t		RTOS_TaskGetPriority( RTOS_PID_t * );
// obsolete RTOS_API RTOS_U8_t		RTOS_TaskSetPriority( RTOS_PID_t * , RTOS_U8_t );
// obsolete RTOS_API RTOS_PID_t *	RTOS_TaskGetId( void );
RTOS_API 	void 		RTOS_WaitTask			( RTOS_PID_t * );
RTOS_API 	void 		RTOS_TaskYield			( void );
RTOS_API 	void 		RTOS_TaskYieldISR		( void );
#			define 		RTOS_GetTCB(__task__) 	&(__task__##TCB)
#			define 		RTOS_GetPID(__task__) 	&(__task__##PID)
RTOS_API	void 		RTOS_TaskResumeISR		( RTOS_PID_t * );
RTOS_API	void 		RTOS_TaskSuspendISR		( RTOS_PID_t * );


/* RTOS EVENT MANAGEMENT API  */

RTOS_API 	void 		RTOS_SetEvent			( RTOS_EVT_t * );
RTOS_API 	void 		RTOS_SetEventISR		( RTOS_EVT_t * );		// formerly RTOS_IntSetEvent
RTOS_API 	void 		RTOS_WaitEvent			( RTOS_EVT_t * );

RTOS_API RTOS_EST_t		RTOS_TestEvent			( RTOS_EVT_t * );
RTOS_API RTOS_EST_t 	RTOS_TestEventISR		( RTOS_EVT_t * );		// formerly RTOS_TestEventISR

RTOS_API 	void 		RTOS_ResetEvent			( RTOS_EVT_t * );
RTOS_API 	void 		RTOS_ResetObjectEvent	( RTOS_OBJ_t * );		// obsolete, to be used only inside Kernel 

RTOS_API RTOS_EST_t 	RTOS_TestTaskID			( RTOS_PID_t * );		// is it really needed

/* RTOS MESSAGE MANAGEMENT API */

#define RTOS_GetMessageData(__msg__,__type__) 				\
	(*((__type__*)(__msg__##_dptr)))
	
#define RTOS_PutMessageData(__msg__,__data__,__type__)		\
	*((__type__*)(__msg__##_dptr)) = *(&__data__)

RTOS_API RTOS_MSG_t *	RTOS_RecvMessage		( RTOS_MSQ_t * );
RTOS_API RTOS_MSG_t * 	RTOS_WaitMessage		( RTOS_MSQ_t * );
RTOS_API 	void 		RTOS_SendMessage		( RTOS_MSQ_t * , RTOS_MSG_t * );
RTOS_API 	void 		RTOS_SendMessageISR		( RTOS_MSQ_t * , RTOS_MSG_t * );
RTOS_API 	void 		RTOS_AckMessage			( RTOS_MSG_t * );
RTOS_API 	void 		RTOS_WaitMessageAck		( RTOS_MSG_t * );
RTOS_API RTOS_EST_t 	RTOS_TestMessageAck		( RTOS_MSG_t * );

/* RTOS TIMER MANAGEMENT API */

RTOS_API 	void 		RTOS_StartTimer			( RTOS_TMR_t * , RTOS_U16_t count );
RTOS_API RTOS_TMR_t * 	RTOS_CancelTimer		( RTOS_TMR_t * );
RTOS_API 	void 		RTOS_Delay				( RTOS_TMR_t * , RTOS_U16_t count);
RTOS_API 	void 		RTOS_WaitTimer			( RTOS_TMR_t * );
RTOS_API RTOS_EST_t  	RTOS_TestTimer			( RTOS_TMR_t * );

RTOS_API	void		RTOS_StartTimerMessage	( RTOS_TMS_t * , RTOS_U16_t , RTOS_MSQ_t * );
RTOS_API RTOS_MSG_t *	RTOS_CancelTimerMessage	( RTOS_TMS_t * , RTOS_MSQ_t * );

RTOS_API RTOS_U16_t		RTOS_GetTime			( void );
RTOS_API RTOS_U16_t		RTOS_GetTimeISR			( void );

RTOS_API 	void 		RTOS_TimerHandlerFNC	( void );    // Kernel Function called by timer ISR

/* RTOS TIMER MESSAGE MANAGEMENT API */

// -= TBD =- RTOS_API 	void 		RTOS_StartTimerMessage	( RTOS_TMS_t * timer , RTOS_U16_t count , RTOS_MSQ_t * queue);
// -= TBD =- RTOS_API pRtosMessage 	RTOS_CancelTimerMessage	( RTOS_TMS_t * timer , RTOS_MSQ_t * queue );

/******************************************************************************
** RTOS Debug Log services                                                                   
******************************************************************************/

OBSOLETE	void		RTOS_DebugOutPtr		( void * );				
OBSOLETE	void		RTOS_DebugOutByte		( RTOS_U8_t );			
OBSOLETE	void		RTOS_DebugOutBuff		( void * , RTOS_U8_t );	

RTOS_API	void		RTOS_DebugOutSync		( void );
RTOS_API	void		RTOS_DebugOutAddr		( void * );				
RTOS_API	void		RTOS_DebugOutData		( void * , RTOS_U8_t );				
RTOS_API	void		RTOS_DebugOutDump		( void );

/* rtos_debug_ex.S */
RTOS_API	void 		RTOS_DebugOutArgs		( const char * fmt, ... );
RTOS_API	void 		RTOS_DebugOutKDump		( void );

/******************************************************************************
** EOF                                                                  
******************************************************************************/
#endif /* __RTOS_H__ */
